#include "StdAfx.h"
//-------------------------------------------------------------------------------------------------
//TinyXMLHelper.cpp  - Implementation of static helper methods for TinyXml             
//-------------------------------------------------------------------------------------------------
//FreeBSD License
//Copyright 2012 Will Stott All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are
//permitted provided that the following conditions are met:
//
//   1. Redistributions of source code must retain the above copyright notice, this list of
//      conditions and the following disclaimer.
//
//   2. Redistributions in binary form must reproduce the above copyright notice, this list
//      of conditions and the following disclaimer in the documentation and/or other materials
//      provided with the distribution.
//
//THIS SOFTWARE IS PROVIDED BY Will Stott ``AS IS'' AND ANY EXPRESS OR IMPLIED
//WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
//FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Will Stott OR
//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
//ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
//ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//The views and conclusions contained in the software and documentation are those of the
//authors and should not be interpreted as representing official policies, either expressed
//or implied, of Will Stott.
//
//----Authors--------------------------------------------------------------------------------------
//created by: will.stott@ucl.ac.uk Feb 2012
//
//----Comments-------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------

#include "TinyXmlHelper.h"


const char * const TinyXmlHelper::xmlBadAttrib = "NullAttrib";
const char * const TinyXmlHelper::xmlDocName = "Doc";
const char * const TinyXmlHelper::xmlHeaderElementName = "Header";
const char * const TinyXmlHelper::xmlBodyElementName = "Body";

TinyXmlHelper::TinyXmlHelper(void)
{

}


TinyXmlHelper::~TinyXmlHelper(void)
{
}

bool TinyXmlHelper::IsValidXml(const wchar_t *documentName)
{
	bool rc = false;

	if (documentName != '\0')
	{
		TiXmlDocument *pDoc = new TiXmlDocument();
		if (pDoc != '\0')
		{
			char pTempBuffer[ TinyXmlHelper::PATHFILENAMELEN+1];
			wcstombs(pTempBuffer, documentName,  TinyXmlHelper::PATHFILENAMELEN );
			if ( pDoc->LoadFile(pTempBuffer)) 
			{
				rc = true;
			}
			delete pDoc;
		}
	}
	return rc;
}

//XML elements must follow these naming rules:
// Names can contain letters, numbers, and other characters
// Names cannot start with a number or punctuation character
// Names cannot start with the letters xml (or XML, or Xml, etc)
// Names cannot contain spaces

const char *TinyXmlHelper::MakeWellFormedAttributeName(std::string &AttribName, int AttribNameLengthMax)
{
	using namespace std;

	basic_string <char>::size_type  index;
	basic_string <char>::size_type  lengthMax = AttribNameLengthMax;

	if ((AttribName.length() == 0 ) || (AttribNameLengthMax == 0))
		AttribName = TinyXmlHelper::xmlBadAttrib;
	else
	{
		char p = AttribName[0];
		if ( (p == 'x') || (p == 'x'))
			AttribName[0] = 'Y';		//avoid Xml
		if (isalpha(p) == false)
			AttribName[0] = 'Z';		//avoid numbers or punctuation

		string name;
		while ((index = AttribName.find(" ", 0)) != string::npos)
		{
			name = AttribName;
			AttribName = name.replace(index,1,"-");
		}
		if ( AttribName.length() > lengthMax)
			AttribName.resize(lengthMax);
	}
	return AttribName.c_str();
}

TiXmlElement *TinyXmlHelper::GetHeaderElement(TiXmlDocument *pDocument)
{
	TiXmlElement *rc = '\0';

	if (pDocument != '\0')
	{
		for( TiXmlElement *child = pDocument->FirstChildElement(); (child != '\0') && (rc == '\0'); child = child->NextSiblingElement() )
		{
			std::string val = child->Value();
			if ( val == TinyXmlHelper::xmlDocName )
			{
				TiXmlElement *doc = child;
				for( TiXmlElement *child = doc->FirstChildElement(); child; child = child->NextSiblingElement() )
				{
					val = child->Value();
					if ( val == TinyXmlHelper::xmlHeaderElementName)
					{
						rc = child;
						break;
					}
				}
			}
		}
	}
	return rc;
}

TiXmlElement *TinyXmlHelper::GetBodyElement(TiXmlDocument *pDocument)
{
	TiXmlElement *rc = '\0';

	if (pDocument != '\0')
	{
		for( TiXmlElement *child = pDocument->FirstChildElement();  (child != '\0') && (rc == '\0'); child = child->NextSiblingElement() )
		{
			std::string val = child->Value();
			if ( val == TinyXmlHelper::xmlDocName )
			{
				TiXmlElement *doc = child;
				for( TiXmlElement *child = doc->FirstChildElement(); child; child = child->NextSiblingElement() )
				{
					val = child->Value();
					if ( val == TinyXmlHelper::xmlBodyElementName)
					{
						rc = child;
						break;
					}
				}
			}
		}
	}
	return rc;
}

TiXmlElement *TinyXmlHelper::FindChildXmlElement(TiXmlElement *parent, const char *Name)
{
	TiXmlElement *rc = '\0';

	if ( parent != '\0' )
	{
		for( TiXmlNode *child = parent->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *element = dynamic_cast<TiXmlElement *>(child);
				if (element != '\0')
				{
					std::string val = element->Value();
					if ( val == Name)
					{
						rc = element;
						break;
					}
				}
			}
		}
	}
	return rc;
}

TiXmlElement *TinyXmlHelper::GetChildXmlElementMatchingText(TiXmlElement *parent, const char *Name, const char *Text)
{
	TiXmlElement *rc = '\0';

	if ( parent != '\0' )
	{
		for( TiXmlNode *child = parent->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *element = dynamic_cast<TiXmlElement *>(child);
				if (element != '\0')
				{
					std::string val = element->Value();
					if ( val == Name)
					{
						std::string txt = element->GetText();
						if ( txt == Text)
						{
							rc = element;
							break;
						}
					}
				}
			}
		}
	}
	return rc;
}

int	TinyXmlHelper::GetChildElementCnt(TiXmlElement *parent, const char *childElementName)
{
	int rc = -1;

	if ( (parent != '\0' ) && (childElementName != '\0'))
	{
		rc = 0;
		for( TiXmlNode *child = parent->FirstChild(); child; child = child->NextSibling() )
		{
			if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
			{
				TiXmlElement *element = dynamic_cast<TiXmlElement *>(child);
				if (element != '\0')
				{
					std::string val = element->Value();
					if ( val == childElementName)
					{
						rc++;
					}
				}
			}
		}
	}
	return rc;
}

TiXmlElement *TinyXmlHelper::DeepCopyXmlElement(TiXmlElement *src)
{
	TiXmlElement *rc = '\0';

	if (src != '\0')
		rc = dynamic_cast<TiXmlElement *>(src->Clone());

	return rc;
}


//-------------------------------------------------------------------------------------------------
//			E N D   O F   F I L E
//-------------------------------------------------------------------------------------------------